home *** CD-ROM | disk | FTP | other *** search
/ Delphi 2.0 - Programmer's Utilities Power Pack / Delphi 2.0 Programmer's Utilities Power Pack.iso / m_to_r / resizer2 / resizer.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1996-09-15  |  9.3 KB  |  308 lines

  1. {
  2.    Resizer.Pas
  3.    ***********
  4.  
  5.    TTabbedNotebook functionality added by:
  6.  
  7.             Jeff Kinzer
  8.             102413,2557
  9. }
  10.  
  11. {*
  12.  * NO THIS IS NOT PERFECT. IF YOU DON'T LIKE IT, DON'T USE IT!
  13.  *
  14.  * This is a simple VC that resizes all the controls on a form.
  15.  *
  16.  * All you have to do is place the RESIZER component on your form,
  17.  * set the 'OnSized' event for the form to a function and then call
  18.  * 'ReSize(Sender)' from within that function.
  19.  *
  20.  * It is a GOOD IDEA in your 'OnSized' event for the form to watch
  21.  * for resizing that is too small. If you resize the form too small
  22.  * you can cause this Resizer to crash your program. All you have to
  23.  * do is check the bounds of the form being resized, if they are less
  24.  * than a certain amount, set the bounds to the certain amount.
  25.  *
  26.  * See the example program for help or you can mail me:
  27.  *   mental@murdrum.nmsu.edu
  28.  *
  29.  * Obvious extensions are adding support to any container controls I
  30.  * may have missed. You can tell if something is a container control
  31.  * by placing another control on it and then try to move the control
  32.  * outside of it. If you cannot move the inner control outside, it
  33.  * IS a container control.
  34.  * I have NOT figured out how controls are stored on a TTabbedNotebook,
  35.  * (but honently I have not looked very hard, yet) so while the
  36.  * TTabbedNotebook will resize itself, the obejcts on the pages will
  37.  * not size themselvess.
  38.  *}
  39.  
  40. unit Resizer;
  41.  
  42. interface
  43.  
  44. uses
  45.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  46.   Forms, Dialogs, ExtCtrls, StdCtrls, TabNotBk;
  47.  
  48. type
  49.   pControlInfo = ^tControlInfo;
  50.   tControlInfo = record
  51.      { This record holds information about a component on the form}
  52.      { or about a component inside a container object}
  53.      Obj:TControl;
  54.      ClassName:String;
  55.      lRatio,tRatio,wRatio,hRatio:Real;
  56.      Contains:pControlInfo;
  57.      Next:pControlInfo;
  58.   End;
  59.   TResizer = class(TComponent)
  60.   private
  61.     { These variables and functions should not be needed by the user, }
  62.     { only by the RESIZER component.}
  63.      ResizerInitialized:Boolean;
  64.      Function  GetClientControlCount(Sender:TObject):LongInt;
  65.      procedure GetNewWidthHeight(Sender:TObject;Var NewW,NewH:LongInt);
  66.      Procedure PerformResize(CurCont:pControlInfo;CWidth,CHeight:LongInt);
  67.      Function  GetClientControlObject(Sender:TObject;Index:LongInt):TControl;
  68.      Function  Initialize(Sender:TObject;CWidth,CHeight:LongInt):pControlInfo;
  69.      Procedure DeleteControlList(CurCont:pControlInfo);
  70.   public
  71.     constructor Create(AOwner: TComponent); override;
  72.     destructor  Destroy; override;
  73.     { These are useful to the programmer. I currently dont use NewShapshot, but}
  74.     { somebody out there might.... especially if you are using DYNAMICALLY}
  75.     { created components on your form.}
  76.     procedure   ReSize(ParentForm:TObject);
  77.     procedure   NewSnapshot(ParentForm:TObject);
  78.   end;
  79.  
  80. procedure Register;
  81.  
  82. implementation
  83.  
  84. Var ControlList:pControlInfo;
  85.  
  86. constructor TResizer.Create(AOwner: TComponent);
  87. Var Count:LongInt;
  88. Begin
  89.    inherited Create(AOwner);
  90.    { Do my init stuff}
  91.    ResizerInitialized:=False;
  92.    ControlList:=nil;
  93. End;
  94.  
  95. destructor TResizer.Destroy;
  96. Begin
  97.    { Destroy the existing ControlList }
  98.    DeleteControlList(ControlList);
  99.    ResizerInitialized:=False;
  100.    ControlList:=nil;
  101.    inherited Destroy;
  102. End;
  103.  
  104. { Recursively setup throw the control list and all containers}
  105. { and delete all the dynamically allocated objects}
  106. Procedure TResizer.DeleteControlList(CurCont:pControlInfo);
  107. Var NextCont:pControlInfo;
  108. Begin
  109.    While(CurCont<>nil) Do
  110.    Begin
  111.       If((CurCont^.Contains)<>nil) Then
  112.          DeleteControlList(CurCont^.Contains);
  113.       NextCont:=CurCont^.Next;
  114.       FreeMem(CurCont,SizeOf(tControlInfo));
  115.       CurCont:=NextCont;
  116.    End;
  117. End;
  118.  
  119. procedure TResizer.GetNewWidthHeight(Sender:TObject;Var NewW,NewH:LongInt);
  120. var
  121.    Ctl: TControl;
  122.    PageNum: LongInt;
  123. Begin
  124.    { Determine the type of container component we have then get its}
  125.    { width and height and tag number}
  126.    If(Sender is TForm) Then
  127.    With TForm(Sender) Do
  128.    Begin
  129.       { Since this is a TForm, we want ClientWidth and ClientHeight}
  130.       NewW:=ClientWidth;
  131.       NewH:=ClientHeight;
  132.    End
  133.    Else
  134.    If(Sender is TPanel) Then
  135.    With TPanel(Sender) Do
  136.    Begin
  137.       NewW:=Width;
  138.       NewH:=Height;
  139.    End
  140.    Else
  141.    If(Sender is TGroupBox) Then
  142.    With TGroupBox(Sender) Do
  143.    Begin
  144.       NewW:=Width;
  145.       NewH:=Height;
  146.    End
  147.    Else
  148.    If(Sender is TTabbedNotebook) Then
  149.    begin
  150.       PageNum := (TTabbedNotebook(Sender).PageIndex * 2) + 1;
  151.       Ctl := TTabbedNotebook(Sender).Controls[PageNum];
  152.       With TTabPage(Ctl) Do
  153.       Begin
  154.          NewW:=Width;
  155.          NewH:=Height;
  156.       End;
  157.    end
  158.    Else
  159.    Begin
  160.       { We don't recognize the container, so supply 0 values}
  161.       NewW:=0;
  162.       NewH:=0;
  163.    End;
  164. End;
  165.  
  166. Function TResizer.GetClientControlCount(Sender:TObject):LongInt;
  167. var
  168.    Ctl: TControl;
  169.    PageNum: LongInt;
  170. Begin
  171.    { Determine the type of container component we have then}
  172.    { return the number of controls on that container}
  173.    If(Sender is TForm) Then
  174.       Result:=TForm(Sender).ControlCount
  175.    Else
  176.    If(Sender is TPanel) Then
  177.       Result:=TPanel(Sender).ControlCount
  178.    Else
  179.    If(Sender is TGroupBox) Then
  180.       Result:=TGroupBox(Sender).ControlCount
  181.    Else
  182.    If(Sender is TTabbedNotebook) Then
  183.    begin
  184.       PageNum := (TTabbedNotebook(Sender).PageIndex * 2) + 1;
  185.       Ctl := TTabbedNotebook(Sender).Controls[PageNum];
  186.       Result := TTabPage(Ctl).ControlCount
  187.    end
  188.    Else
  189.       { We don't recognize the container, so supply a 0 value}
  190.       Result:=0;
  191. End;
  192.  
  193.  
  194. Function TResizer.GetClientControlObject(Sender:TObject;Index:LongInt):TControl;
  195. var
  196.    Ctl: TControl;
  197.    PageNum: LongInt;
  198. Begin
  199.    If(Sender is TForm) Then
  200.       Result:=TForm(Sender).Controls[Index]
  201.    Else
  202.    If(Sender is TPanel) Then
  203.       Result:=TPanel(Sender).Controls[Index]
  204.    Else
  205.    If(Sender is TGroupBox) Then
  206.       Result:=TGroupBox(Sender).Controls[Index]
  207.    Else
  208.    If(Sender is TTabbedNotebook) Then
  209.    begin
  210.       PageNum := (TTabbedNotebook(Sender).PageIndex * 2) + 1;
  211.       Ctl := TTabbedNotebook(Sender).Controls[PageNum];
  212.       Application.MainForm.Caption := Ctl.ClassName + '  ' + IntToStr(TWinControl(Ctl).ControlCount);
  213.       if Index < TWinControl(Ctl).ControlCount then
  214.          Result := TTabPage(Ctl).Controls[Index]
  215.       else
  216.          Result := nil;
  217.    end
  218.    Else
  219.       Result:=nil;
  220. End;
  221.  
  222. Function TResizer.Initialize(Sender:TObject;CWidth,CHeight:LongInt):pControlInfo;
  223. Var Temp:pControlInfo;
  224.     Count:Integer;
  225. Begin
  226.    Result:=nil;
  227.    For Count:=0 to (GetClientControlCount(Sender)-1) Do
  228.    Begin
  229.       GetMem(Temp,SizeOf(tControlInfo));
  230.       Temp^.Obj:=GetClientControlObject(Sender,Count);
  231.       With(Temp^) Do
  232.       Begin
  233.          lRatio:=(Obj.Left) / CWidth;
  234.          tRatio:=(Obj.Top) / CHeight;
  235.          wRatio:=(Obj.Width) / CWidth;
  236.          hRatio:=(Obj.Height) / CHeight;
  237.          Contains:=nil;
  238.          Next:=Result;
  239.       End;
  240.       Result:=Temp;
  241.       If((Temp^.Obj is TForm) or
  242.          (Temp^.Obj is TPanel) or
  243.          (Temp^.Obj is TGroupBox) or
  244.          (Temp^.Obj is TTabbedNotebook)) Then
  245.       With(Temp^) Do
  246.          Contains:=Initialize(Obj,Obj.Width,Obj.Height);
  247.    End;
  248. End;
  249.  
  250. Procedure TResizer.PerformResize(CurCont:pControlInfo;CWidth,CHeight:LongInt);
  251. Begin
  252.    While(CurCont<>nil) Do
  253.    Begin
  254.       With(CurCont^) Do
  255.       Begin
  256.          With(Obj) Do
  257.             SetBounds(Round(lRatio*CWidth),Round(tRatio*CHeight),
  258.                Round(wRatio*CWidth),Round(hRatio*CHeight));
  259.          If(Contains<>nil) Then
  260.             PerformResize(Contains,Obj.Width,Obj.Height);
  261.       End;
  262.       CurCont:=CurCont^.Next;
  263.    End;
  264. End;
  265.  
  266. procedure TResizer.NewSnapshot(ParentForm:TObject);
  267. Var NewClientWidth,NewClientHeight:LongInt;
  268. Begin
  269.    GetNewWidthHeight(ParentForm,NewClientWidth,NewClientHeight);
  270.    { Delete the existing ControlList for this form}
  271.    DeleteControlList(ControlList);
  272.    ControlList:=nil;
  273.    ResizerInitialized:=False;
  274.    { Initialize the ControlList for this form}
  275.    ControlList:=Initialize(ParentForm,NewClientWidth,NewClientHeight);
  276.    If(ControlList<>nil) Then
  277.       { The control list HAS been initialized!}
  278.       ResizerInitialized:=True;
  279. End;
  280.  
  281. { This should be called everytime the form is resized (ie in the OnSized}
  282. { event). Pass OnSized "Sender" parameter to this procedure}
  283. procedure TResizer.ReSize(ParentForm:TObject);
  284. Var NewClientWidth,NewClientHeight:LongInt;
  285.     Count:Integer;
  286.     Left,Top,Width,Height:LongInt;
  287. Begin
  288.    GetNewWidthHeight(ParentForm,NewClientWidth,NewClientHeight);
  289.    If(ResizerInitialized) Then
  290.       { The ControlList already exists, resize the form and its controls}
  291.       PerformResize(ControlList,NewClientWidth,NewClientHeight)
  292.    Else
  293.       { No ControlList exists. Let's create one}
  294.       NewSnapshot(ParentForm);
  295. End;
  296.  
  297. { This should be called only if you want to take a NEW shapshot of the}
  298. { relative positions and sizes of the controls on the form. The paramter}
  299. { should be the form on which the object resides}
  300. procedure Register;
  301. begin
  302.    { Register the RESIZER component}
  303.    RegisterComponents('New VCs', [TResizer]);
  304. end;
  305.  
  306. end.
  307.  
  308.